package org.example.readwritelock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author ZhengDp
 * @Date 2023/1/19 19:16
 */
@Slf4j(topic = "c.CachedData")
public class CachedData {

    Object data;
    volatile boolean cacheValid;

    final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();

    void processCachedData () {
        rw.readLock().lock();
        if(!cacheValid) {
            // 获取写锁之前必须释放读锁
            rw.readLock().unlock();
            rw.writeLock().lock();
            try {
                // 判断是否有其他线程已经获取了写锁，更新了缓存，避免重复更新
                if(!cacheValid) {
                    data = "123";
                    cacheValid = true;
                }
                // 降级为读锁，释放写锁，这样能够让其他线程读取缓存
                rw.readLock().lock();
            } finally {
                rw.writeLock().unlock();
            }
        }
        // 自己用完数据，释放读锁
        try {
            use(data);
        }finally {
            rw.readLock().unlock();
        }
    }

    private void use(Object data) {
        log.info("{}",data);
    }

}
